package com.OpenSURF;

import com.OpenSURF.swig.Ipoint;
import com.OpenSURF.swig.IpointVector;
import com.OpenSURF.swig.SURFjni;
import com.jsurf.InterestPoint;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;

/**
 * Created by: Eduardo Quintana Contreras
 * Date: 23/06/11
 * Time: 04:06 PM
 */
public class OpenSurf {

	/**
	 * Gets the {@code interest-points} of an image using a c++ library.
	 *
	 * @param imgFilename the filename of the image to be processed
	 * to obtain its interest points
	 * @param threshold the {@code SURF} threshold value. Increase it
	 * to obtain less interest-points
	 * @return an {@code ArrayList} of {@link InterestPoint} objects
	 * found in the image {@code imgFilename}
	 */
	public static ArrayList<InterestPoint> getInterestPoints(String imgFilename, float threshold) {
		try {
//			long begin, end;
//			begin = System.currentTimeMillis();
			BufferedImage bufferedImage = ImageIO.read(new File(imgFilename));
			int width = bufferedImage.getWidth();
			int height = bufferedImage.getHeight();
			int [] pixels = new int[width * height];
			bufferedImage.getRGB(0, 0, width, height, pixels, 0, width);

			SURFjni surf = new SURFjni(pixels, width, height);
			surf.surfDetDes(false, 4, 4, 2, threshold);

//			end = System.currentTimeMillis() - begin;
//			System.out.println("cpp Points: " + surf.getIpts().size()/* + ", " + numMatches2*/ + ", " + end / 1000d);

			return toJInterestPoints(surf.getIpts());

		} catch(IOException e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * Casts a vector of {@link Ipoint} objects into an {@code ArrayList}
	 * of {@link InterestPoint} objects.
	 *
	 * @param cppIpoints the vector of {@link Ipoint} objects,
	 * calculated with the c++ library
	 * @return an {@code ArrayList} of {@link InterestPoint} objects
	 */
	public static ArrayList<InterestPoint> toJInterestPoints(IpointVector cppIpoints) {
//		long begin, end;
//		begin = System.currentTimeMillis();
		ArrayList<InterestPoint> jIpoints = new ArrayList<InterestPoint>();
		for (int i = 0; i < cppIpoints.size(); i++) {
			Ipoint cppIpoint = cppIpoints.get(i);
			InterestPoint jIpoint = new InterestPoint(cppIpoint.getX(), cppIpoint.getY(), cppIpoint.getScale(),
					cppIpoint.getLaplacian());
			jIpoint.setDescriptor(cppIpoint.getDescriptor());
			jIpoint.setOrientation(cppIpoint.getOrientation());
			jIpoints.add(jIpoint);
		}
//		end = System.currentTimeMillis() - begin;
//		System.out.println("Cast:" + jIpoints.size() + ", " + end / 1000d);
		return jIpoints;
	}

	/*public static void getMatches(String img1, String img2) {
		try {
			long begin, end;

			BufferedImage bufferedImage1 = ImageIO.read(new File(img1));
			int width = bufferedImage1.getWidth();
			int height = bufferedImage1.getHeight();
			int [] pixels = new int[width * height];
			bufferedImage1.getRGB(0, 0, width, height, pixels, 0, width);

			SURFjni surf1 = new SURFjni(pixels, width, height);
			surf1.surfDetDes(false, 4, 4, 2, 0.0001f);

			BufferedImage bufferedImage2 = ImageIO.read(new File(img2));
			width = bufferedImage2.getWidth();
			height = bufferedImage2.getHeight();
			pixels = new int[width * height];
			bufferedImage2.getRGB(0, 0, width, height, pixels, 0, width);

			SURFjni surf2 = new SURFjni(pixels, width, height);
			surf2.surfDetDes(false, 4, 4, 2, 0.0001f);

			begin = System.currentTimeMillis();

			IpPairVector matches = new IpPairVector();
			opensurf.getMatches(surf1.getIpts(), surf2.getIpts(), matches);

			end = System.currentTimeMillis() - begin;
			System.out.println("cpp matches: " + matches.size()*//* + ", " + numMatches2*//* + ", " + end / 1000d);

		} catch(IOException e) {
			e.printStackTrace();
		}
	}*/
}
